package com.dudu.controller;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;

import com.dudu.bean.AccountBean;
import com.dudu.bean.AppExtendBean;
import com.dudu.enumeration.AbilityTypeEnum;
import com.dudu.enumeration.H5CodeDefinition;
import com.dudu.model.BootRequestParamters;
import com.dudu.model.CheckResult;
import com.dudu.service.IAccountExtendService;
import com.dudu.service.IAppExtendService;
import com.dudu.service.ICheckValidityService;
import com.dudu.service.IOperationPlatformCustAccountService;
import com.dudu.service.IPay;
import com.dudu.service.impl.AccountExtendServiceImpl;
import com.dudu.service.impl.AppExtendServiceImpl;
import com.dudu.service.impl.CheckValidityServiceImpl;
import com.dudu.service.impl.OperationPlatformCustAccountServiceImpl;
import com.dudu.service.impl.PayServiceImpl;
import com.dudu.utils.Encrypt;
import com.dudu.utils.H5CheckUtils;

import core.CoreService;
import core.util.CommUtils;
import core.util.Const;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * h5插件控制类
 * 
 * @author zx
 *
 */
public class H5Controller extends CoreService implements IH5Controller {

	private IAppExtendService appExtendService = new AppExtendServiceImpl();

	private ICheckValidityService checkValidityService = new CheckValidityServiceImpl();

//	private IOperationPlatformService operationPlatformService = new OperationPlatformServiceImpl();

	private IAccountExtendService accountExtendService = new AccountExtendServiceImpl();

	private IPay payService = new PayServiceImpl();

	/**
	 * h5插件入口 校验应用账户和组织账户信息 传入参数如下： 1）account_identifer-应用账户-不能为空
	 * 2）sign-应用账户的认证码-不能为空 3）timestamp-应用账户的时间戳-不能为空
	 * 4）caller_info-主叫信息-包含name（主叫姓名）和telephone（主叫电话）的JSON格式字符串，
	 * name和telephone均不能为空 5）account_identify-组织账户-可以为空
	 * 6）company_info-组织机构信息-包含： company_identifer-组织标识-不能为空 name-组织名称
	 * telephone-联系电话 linker-联系人 email-邮箱 注：5和6至少要传入一个
	 */
	public String bootstrap() {
		BootRequestParamters params = new BootRequestParamters();
		HttpServletRequest request = this.getRequest();
		params.setAppKey(request.getParameter("app_key"));
		params.setSign(request.getParameter("sign"));
		params.setTimestamp(request.getParameter("timestamp"));
		params.setAuthData(request.getParameter("authData"));
		params.setCustAccount(request.getParameter("cust_account"));
		params.setCallerInfo(request.getParameter("caller"));
		String isAdmin = this.getRequest().getParameter("isadmin");
		if ("1".equals(isAdmin)) {
			params.setAdmin(true);
		} else
			params.setAdmin(false);
		CheckResult nullCheckResult = checkNullParametersForBost(params);// 校验输入参数是否为空
		String callback = request.getParameter("callback");
		if (!nullCheckResult.isCheckedThrough())
			return returnResult(nullCheckResult.getResult(), callback);
		AppExtendBean appExtendBean = appExtendService.queryAppExtendByIdentify(params.getAppKey());
		/** 没有查询到应用信息 **/
		if (appExtendBean == null)
			return returnResult(H5CheckUtils.transformCodeDefinition(H5CodeDefinition.NOT_EXISTS_APPACCOUNT), callback);
		/** 认证码校验未通过 **/
		if (!checkValidityService.toolsCheckSign(params.getAppKey(), appExtendBean.getKey_private(),
				params.getTimestamp(), params.getSign()))
			return returnResult(H5CheckUtils.transformCodeDefinition(H5CodeDefinition.ERROR_SIGN), callback);
		JSONObject companyInfo = JSONObject.fromObject(params.getAuthData());
		String company_identifer = companyInfo.getString("ext_orgCode");

		/** 调用运营平台接口判断 **/
		IOperationPlatformCustAccountService ia = new OperationPlatformCustAccountServiceImpl();
		String info = ia.getAppCustInfo(company_identifer, params.getAppKey());
		JSONObject oinfo = JSONObject.fromObject(info);
		log.info(info);
		String code = oinfo.getString("flag");
		if ("0000".equals(code)) {// 成功
			if (!StringUtils.isEmpty(params.getCustAccount())) {// 判断输入的计费账户是否和运营平台返回的结果是否一致
				JSONArray jo = oinfo.getJSONArray("data");
				boolean match = false;
				for (int i = 0, l = jo.size(); i < l; i++) {
					String ca = jo.getJSONObject(i).getString("cust_account");
					if (ca.equals(params.getCustAccount())) {
						match = true;
						break;
					}
				}
				if (!match)
					return returnResult(H5CheckUtils.transformCodeDefinition(H5CodeDefinition.UNMATCH_ORGACCOUNT),
							callback);
			} else {// 未传递cust_account计费账号
				JSONArray jo = oinfo.getJSONArray("data");
				if (!jo.isEmpty()) {
					params.setCustAccount(jo.getJSONObject(0).getString("cust_account"));
				}
			}
		} else if ("0020".equals(code)) {// 返回结果为空
			return returnResult(H5CheckUtils.transformCodeDefinition(H5CodeDefinition.UNREGISTERED_COMPANYACCOUNT),
					callback);
		} else/** 运营平台接口抛出的其他异常信息 **/
			return returnResult(H5CheckUtils.transformCodeDefinition("9999", oinfo.getString("desc")), callback);
		AccountBean accountBean = accountExtendService.queryAccountDetailByCustAccount(params.getCustAccount());
		/** 没有查询到组织账号 **/
		if (accountBean == null)
			return returnResult(H5CheckUtils.transformCodeDefinition(H5CodeDefinition.UNAVAILABLE_ORGACCOUNT),
					callback);
		/**校验组织账号余额是否充足
		 * 20160715修改
		 * 余额校验只需要调用一次接口即可，最早是每种能力都需要单独调用一次接口
		 */
		JSONObject data = null;
		JSONObject jb=ia.getAccountBalancesByAbilityType(params.getCustAccount(), AbilityTypeEnum.MPTY.getKey() + ","
				+ AbilityTypeEnum.DIAL.getKey() + "," + AbilityTypeEnum.VOICE.getKey());
		log.info("鉴权结果为=="+jb);
		String mptyBalance=jb.getString(AbilityTypeEnum.MPTY.getKey());
		String dialBalance=jb.getString(AbilityTypeEnum.DIAL.getKey());
		String voiceBalance=jb.getString(AbilityTypeEnum.VOICE.getKey());
		if("1".equals(mptyBalance)||"1".equals(dialBalance)||"1".equals(voiceBalance)){//有一种能力充足即可
			data = new JSONObject();
			data.put("code", H5CodeDefinition.SUCCESS.getCode());
		}else{
			data = H5CheckUtils.transformCodeDefinition(H5CodeDefinition.ACCOUNTBALANCE_INSUFFICIENT);
		}
//		if (!operationPlatformService.platformAuthentication(new JSONObject(), appExtendBean, accountBean,
//				params.getAppKey())
//				&& !operationPlatformService.platformAuthentication(new JSONObject(), appExtendBean, accountBean,
//						"Dial")
//				&& !operationPlatformService.platformAuthentication(new JSONObject(), appExtendBean, accountBean,
//						"VOICE")) {
//			data = H5CheckUtils.transformCodeDefinition(H5CodeDefinition.ACCOUNTBALANCE_INSUFFICIENT);
//		} else {
//			data = new JSONObject();
//			data.put("code", H5CodeDefinition.SUCCESS.getCode());
//		}
		data.put("cust_account", accountBean.getCust_account());
		data.put("periphery_code", appExtendBean.getPeriphery_code());
		setAuthentication(data, accountBean);
		/** 管理员登录需要获取卡密支付相关信息 **/
		if (params.isAdmin()) {
			setPayCardInfo(params.getAppKey(), data);
		}
		return returnResult(data, callback);
	}

	/**
	 * 内部校验输入参数是否为空
	 * 
	 * @param params
	 * @return
	 */
	private CheckResult checkNullParametersForBost(BootRequestParamters params) {
		if (StringUtils.isEmpty(params.getAppKey())) // 应用账号为空
			return returnCheckResult(H5CodeDefinition.NULL_ACCOUNT, false);
		if (StringUtils.isEmpty(params.getSign())) // 认证码为空
			return returnCheckResult(H5CodeDefinition.NULL_SIGN, false);
		if (StringUtils.isEmpty(params.getTimestamp())) // 时间戳为空
			return returnCheckResult(H5CodeDefinition.NULL_TIMESTAMP, false);
		if (StringUtils.isEmpty(params.getCallerInfo())) {// 主叫信息为空
			return returnCheckResult(H5CodeDefinition.NULL_CALLERINFO, false);
		} else {
			JSONObject callerInfo = JSONObject.fromObject(params.getCallerInfo());
			if (callerInfo == null || callerInfo.isEmpty()) // 主叫信息为空
				return returnCheckResult(H5CodeDefinition.NULL_CALLERINFO, false);
			else if (StringUtils.isEmpty(callerInfo.getString("name"))) // 主叫姓名为空
				return returnCheckResult(H5CodeDefinition.NULL_NAME_CALLERINFO, false);
			else if (StringUtils.isEmpty(callerInfo.getString("telephone"))) // 主叫电话为空
				return returnCheckResult(H5CodeDefinition.NULL_TEL_CALLERINFO, false);
		}
		JSONObject companyObject = null;
		if (StringUtils.isEmpty(params.getAuthData())
				|| !(companyObject = JSONObject.fromObject(params.getAuthData())).containsKey("ext_orgName")) {
			return returnCheckResult(H5CodeDefinition.UNKNOWN_COMPANYNAME, false);
		}
		if (StringUtils.isEmpty(params.getAuthData())
				|| (companyObject = JSONObject.fromObject(params.getAuthData())).isEmpty()
				|| StringUtils.isEmpty(companyObject.getString("ext_orgCode"))) {
			return returnCheckResult(H5CodeDefinition.EMPTY_ORGCODE, false);
		}
		return returnCheckResult(H5CodeDefinition.CHECK_THROUGH, true);
	}

	private String returnResult(JSONObject data, String callback) {
		if (StringUtils.isEmpty(callback))
			return returnData(data.toString());
		else
			return returnData(callback + "(" + data.toString() + ")");
	}

	private CheckResult returnCheckResult(H5CodeDefinition code, boolean through) {
		return H5CheckUtils.createResult(code, through);
	}

	@Override
	/**
	 * 组织账户注册接口 组织账号注册成功后，生成认证码 组织账号注册失败的，不做任何处理 传入参数如下：
	 * 1）account_identifer:应用账户，不能为空 2）sign：认证码，不能为空 3）timestamp：时间戳，不能为空
	 * 4）company_identifer：组织标识，不能为空 5）authData：组织信息，不能为空
	 * 6）record_url：话单回传地址，可为空 7）status_url：会议状态回传地址，可为空
	 */
	public String registerAndAuthenticate() {
		HttpServletRequest request = this.getRequest();
		String isAdmin = request.getParameter("isadmin");
		IOpenAccountController registerService = new OpenAccountController();
		CoreService service = (CoreService) registerService;
		service.setRequest(request);
		service.setResponse(this.getResponse());
		service.setSession(this.getSession());
		service.setDao(this.getDao());
		String ext_orgReleCode = request.getParameter("ext_orgReleCode");
		/**
		 * 关联码为空，调用普通注册接口 关联码不为空，调用强制注册接口
		 */
		String regResult;
		if (StringUtils.isEmpty(ext_orgReleCode)) {
			regResult = registerService.orgAccReg();
		} else {
			regResult = registerService.orgAccRegForceJoin();
		}
		JSONObject data = JSONObject.fromObject(regResult);
		data = data.getJSONObject(Const.DATA);
		String code = data.getString("result");
		if ("0".equals(code)) {// 注册成功
			/** 注册成功后给isv传递注册成功的数据 **/
			JSONObject regInfo = data.getJSONObject("data");
			setAuthentication(regInfo, null);
			if ("1".equals(isAdmin)) {
				setPayCardInfo(regInfo.getString("app_key"), data);
			}
			return returnResult(data, null);
		} else {
			return regResult;
		}
	}

	/**
	 * 设置认证码和时间戳
	 * 
	 * @param data
	 * @param account
	 */
	private void setAuthentication(JSONObject data, AccountBean account) {
		String requestTimeStamp = String.valueOf(new Date().getTime());
		data.put("timestamp", requestTimeStamp);
		if (account == null) {
			data.put("sign", Encrypt
					.sha1Encrypt(data.getString("cust_account") + data.getString("org_tempKey") + requestTimeStamp));
		} else {
			data.put("sign",
					Encrypt.sha1Encrypt(account.getCust_account() + account.getKey_private() + requestTimeStamp));
		}
	}

	/**
	 * 设置卡支付相关信息
	 * 
	 * @param appKey
	 *            应用标识
	 * @param data
	 * @return
	 */
	private boolean setPayCardInfo(String appKey, JSONObject data) {
		JSONObject card = payService.queryPayCardInfo(appKey);
		if (card == null || card.isEmpty())
			return false;
		data.putAll(card);
		return true;
	}

	/**
	 * 进入单个h5页面前进行的认证码和账户信息的校验
	 */
	@Override
	public String checkAuthenticateAndAccount() {
		HttpServletRequest request = this.getRequest();
		BootRequestParamters params = new BootRequestParamters();
		params.setAppKey(request.getParameter("app_key"));
		params.setSign(request.getParameter("sign"));
		params.setTimestamp(request.getParameter("timestamp"));
		params.setCustAccount(request.getParameter("cust_account"));
		CheckResult nullCheckResult = checkNullParameters(params);// 校验输入参数是否为空
		String callback = request.getParameter("callback");
		if (!nullCheckResult.isCheckedThrough())
			return returnResult(nullCheckResult.getResult(), callback);
		AppExtendBean appExtendBean = appExtendService.queryAppExtendByIdentify(params.getAppKey());
		/** 没有查询到应用信息 **/
		if (appExtendBean == null)
			return returnResult(H5CheckUtils.transformCodeDefinition(H5CodeDefinition.NOT_EXISTS_APPACCOUNT), callback);
		/** 认证码校验未通过 **/
		if (!checkValidityService.toolsCheckSign(params.getAppKey(), appExtendBean.getKey_private(),
				params.getTimestamp(), params.getSign()))
			return returnResult(H5CheckUtils.transformCodeDefinition(H5CodeDefinition.ERROR_SIGN), callback);
		AccountBean accountBean = accountExtendService.queryAccountDetailByCustAccount(params.getCustAccount());
		if (accountBean == null)
			return returnResult(H5CheckUtils.transformCodeDefinition(H5CodeDefinition.UNAVAILABLE_ORGACCOUNT),
					callback);
		JSONObject data = new JSONObject();
		data.put("cust_account", params.getCustAccount());
		data.put("periphery_code", appExtendBean.getPeriphery_code());
		data.put("code", H5CodeDefinition.SUCCESS.getCode());
		return returnResult(data, callback);
	}

	private CheckResult checkNullParameters(BootRequestParamters params) {
		if (StringUtils.isEmpty(params.getAppKey())) // 应用账号为空
			return returnCheckResult(H5CodeDefinition.NULL_ACCOUNT, false);
		if (StringUtils.isEmpty(params.getSign())) // 认证码为空
			return returnCheckResult(H5CodeDefinition.NULL_SIGN, false);
		if (StringUtils.isEmpty(params.getTimestamp())) // 时间戳为空
			return returnCheckResult(H5CodeDefinition.NULL_TIMESTAMP, false);
		if (StringUtils.isEmpty(params.getCustAccount())) // 组织账号为空
			return returnCheckResult(H5CodeDefinition.NULL_ORGACCOUNT, false);
		return returnCheckResult(H5CodeDefinition.CHECK_THROUGH, true);
	}

	public static void main(String[] args) {
		// JSONObject data=new JSONObject();
		// data.put("periphery_account", "FRWMN007");
		// data.put("app_key", "6FB5DD33212E4F4C2FD9791BDCFA50EA");
		// String
		// result=HttpRequest.postData("http://123.103.9.209:5002/CombinationServer/getAppCustInfo",
		// data.toString());
		//// String
		// result=HttpRequest.postData("http://test.cloud.yonyoutelecom.cn/CombinationServer/getAppCustInfo",
		// data.toString());
		// log.info(result);

		String custAccount = "test1981";
		String url = "http://test.cloud.yonyoutelecom.cn/CombinationServer/queryResourceAndAccount";
		JSONObject o = new JSONObject();
		o.put("cust_account", custAccount);
		String data = CommUtils.postRequestWithJson(url, o.toString());
		JSONObject result = JSONObject.fromObject(data);
		log.info(result);
	}

	@Override
	public String getAccountBalancesByAbilityType() {
		HttpServletRequest request = this.getRequest();
		String custAccount = request.getParameter("cust_account");
		String callback = request.getParameter("callback");
		String abilityType = request.getParameter("ability_type");
		IOperationPlatformCustAccountService caService = new OperationPlatformCustAccountServiceImpl();
		return returnResult(caService.getAccountBalancesByAbilityType(custAccount, abilityType), callback);
	}

}
